import uuid
import unittest
from datetime import datetime, timedelta

from suds.sudsobject import asdict

from Autotests.BaseTest import BaseManservSOAPTestCase
from Config.RunConfig import RunConfig, Options


class Partners(BaseManservSOAPTestCase):
    def __init__(self, *args, **kwargs):
        super(Partners, self).__init__(*args, **kwargs)

    def setUp(self, *args, **kwargs):
        super(Partners, self).setUp(*args, **kwargs)
        self._basePostAddress = {
            'country': 'BY',
            'state': 'state',
            'district': 'district',
            'city': 'Minsk',
            'zipCode': '22000',
            'address': 'address',
        }
        self._baseCompanyInfo = {
            'postAddress': self._basePostAddress,
            'phoneNumber': 'phone',
            'faxNumber': 'fax',
            'websiteAddress': 'website',
            'legalCompanyName': 'legalName',
            'chamberOfCommerceNumber': 'chamber of commerce',
            'vatNumber': 'vat',
            'bankAccountNumber': 'bankAccount',
        }
        self._parentPartnerName = RunConfig().get(Options.Soap.defaultPartner)
        self._partnerName = ''
        self._parentId = self.manserv.GetPartnerInfo(name = self._parentPartnerName).id

        self._basePartnerInfo = {
            'parentId': int(self._parentId),
            'name': '',
            'level': 'Distributor',
            'privilege': 'Regular',
            'childServiceTypes': {
                'string': ['AllInclusive', ],
                },
            'serviceType': 'AllInclusive',
            'state': 'InTrial',
            'weight': 'Dynamic',
            'company': self._baseCompanyInfo,
            'advancedPartnerProperties': {
                'regionId': 0,
                'responsibleUserId': 0,
            },
            'mailingOption': 'Undefined',
        }

    def test_AddPartner(self):
        count = self._getPartnerCount()
        result = self._createPartner()
        self.assertTrue(result.isnumeric())
        countAfter = self._getPartnerCount()
        self.assertEqual(count + 1, countAfter)
        self._deletePartner()

    def test_ChangePartnerState(self):
        partnerId = self._createPartner()
        result = self.manserv.ChangePartnerState(partnerId = partnerId,
                                                 action = {'value': 'ApplyForProduction',},
                                                 reason = 'Test reason')
        self.assertEqual(result, 'WaitingForProduction')
        partnerInfo = self.manserv.GetPartnerInfoById(id = partnerId)
        self.assertEqual(partnerInfo.state, 'WaitingForProduction')

        self._deletePartner()

    def test_EnumerateAdvancedPartnerProperties(self):
        self._createPartner()
        result = self.manserv.EnumerateAdvancedPartnerProperties(parentPartnerId = int(self._parentId),
                                                                 fetchRecursively = False)
        self.assertGreater(len(result.AdvancedPartnerPropertiesInfo), 0)
        self._deletePartner()

    def test_EnumerateAdvancedPartnerPropertiesByPartnerIds(self):
        partnerId = self._createPartner()
        result = self.manserv.EnumerateAdvancedPartnerPropertiesByPartnerIds(partnerIds = [partnerId,])
        self.assertEqual(result.AdvancedPartnerPropertiesInfo[0].partnerId, partnerId)
        self.assertEqual(result.AdvancedPartnerPropertiesInfo[0].regionId, 0)
        self.assertEqual(result.AdvancedPartnerPropertiesInfo[0].responsibleUserId, 0)

        self._deletePartner()

    def test_EnumerateExternalPartnerProperties(self):
        partnerId = self._createPartner()
        expectedProperties = {
            'advCode': None,
            'channelPartnerId': 0,
            'greatPlainsId': 0,
            'locCode': None,
            'partnerId': int(partnerId),
            'searchTerm': None,
        }
        result = self.manserv.EnumerateExternalPartnerProperties(partnerId = [partnerId, ])
        self.assertTrue(self._compareBaseDictionaryAndResultObject(expectedProperties,
                                                                   result.externalPartnerProperties[0]))
        self._deletePartner()

    def test_EnumeratePartnerFeatures(self):
        partnerId = self._createPartner()

        result = self.manserv.EnumeratePartnerFeatures(partnerId = partnerId)
        self.assertGreater(len(result.featureInfo), 0)
        self._deletePartner()

    def test_EnumeratePartnerStateTransitions(self):
        self._createPartner()
        result = self.manserv.EnumeratePartnerStateTransitions()
        self.assertEqual(len(result.stateTransitionInfo), 13)
        self._deletePartner()

    def test_EnumeratePartnerStatesByPeriod(self):
        start = (datetime.now() - timedelta(days = 1)).isoformat()
        end = (datetime.now() + timedelta(days = 1)).isoformat()
        partnerId = self._createPartner()
        result = self.manserv.EnumeratePartnerStatesByPeriod(startTime = start, endTime = end)
        count = len(result.stateRecord)
        self.assertEqual(result.stateRecord[-1].oldState, 'Undefined')
        self.assertEqual(result.stateRecord[-1].newState, self._basePartnerInfo['state'])
        self.assertEqual(result.stateRecord[-1].partnerId, partnerId)
        self.assertEqual(result.stateRecord[-1].userId, 1)

        self.manserv.ChangePartnerState(partnerId = partnerId,
                                        action = {'value': 'ApplyForProduction',},
                                        reason = 'Test reason')

        result = self.manserv.EnumeratePartnerStatesByPeriod(startTime = start, endTime = end)
        countAfter = len(result.stateRecord)
        self.assertEqual(count + 1, countAfter)
        self.assertEqual(result.stateRecord[-1].oldState, self._basePartnerInfo['state'])
        self.assertEqual(result.stateRecord[-1].newState, 'WaitingForProduction')
        self.assertEqual(result.stateRecord[-1].partnerId, partnerId)
        self.assertEqual(result.stateRecord[-1].userId, 1)

        self._deletePartner()

    def test_EnumeratePartnerUrls(self):
        partnerId = self._createPartner()
        result = self.manserv.EnumeratePartnerUrls(partnerId = partnerId)
        self.assertEqual(len(result.url), 4)
        self._deletePartner()

    def test_EnumeratePartners(self):
        partnerId = self._createPartner()
        result = self.manserv.EnumeratePartners(parentPartnerId = self._parentId,
                                                fetchRecursively = False,
                                                partnerFields = ['',])
        partnerInfo = result.partnerInfo[-1]
        self.assertEqual(len(asdict(partnerInfo)), 5)
        self.assertEqual(partnerInfo.parentId, int(self._parentId))
        self.assertEqual(partnerInfo.level, self._basePartnerInfo['level'])
        self.assertEqual(partnerInfo.id, partnerId)
        self.assertIsNone(partnerInfo.comment)

        self._deletePartner()

    def test_EnumeratePartnersAtTime(self):
        time = (datetime.now() + timedelta(days = 1)).isoformat()
        partnerId = self._createPartner()
        result = self.manserv.EnumeratePartnersAtTime(parentPartnerId = int(self._parentId),
                                                      fetchRecursively = False,
                                                      time = time)
        self.assertGreater(len(result.partnerInfo), 0)
        self.assertTrue(self._compareBaseDictionaryAndResultObject(self._basePostAddress,
                                                                   result.partnerInfo[-1].company.postAddress))
        self.assertTrue(self._compareBaseDictionaryAndResultObject(self._baseCompanyInfo,
                                                                   result.partnerInfo[-1].company))
        self.assertTrue(self._compareBaseDictionaryAndResultObject(self._basePartnerInfo, result.partnerInfo[-1]))
        self.assertEqual(result.partnerInfo[-1].id, partnerId)

        self._deletePartner()

    def test_GetAdvancedPartnerProperties(self):
        partnerId = self._createPartner()
        result = self.manserv.GetAdvancedPartnerProperties(partnerId = partnerId)
        self.assertEqual(self._basePartnerInfo['advancedPartnerProperties']['regionId'],
                         result.regionId)
        self.assertEqual(self._basePartnerInfo['advancedPartnerProperties']['responsibleUserId'],
                         result.responsibleUserId)
        self._deletePartner()

    def test_GetPartnerInfo(self):
        self._createPartner()
        result = self.manserv.GetPartnerInfo(name = self._partnerName)

        self.assertTrue(self._compareBaseDictionaryAndResultObject(self._basePostAddress, result.company.postAddress))
        self.assertTrue(self._compareBaseDictionaryAndResultObject(self._baseCompanyInfo, result.company))
        self.assertTrue(self._compareBaseDictionaryAndResultObject(self._basePartnerInfo, result))

        self._deletePartner()

    def test_GetPartnerInfoById(self):
        partnerId = self._createPartner()
        result = self.manserv.GetPartnerInfoById(id = partnerId)

        self.assertTrue(self._compareBaseDictionaryAndResultObject(self._basePostAddress, result.company.postAddress))
        self.assertTrue(self._compareBaseDictionaryAndResultObject(self._baseCompanyInfo, result.company))
        self.assertTrue(self._compareBaseDictionaryAndResultObject(self._basePartnerInfo, result))

        self._deletePartner()

    def test_GetPartnerPriceCurrency(self):
        partnerId = self._createPartner()
        result = self.manserv.GetPartnerPriceCurrency(partnerId = partnerId)
        self.assertEqual(result, 'EUR')

        self._deletePartner()

    def test_GetPartnerUrl(self):
        partnerId = self._createPartner()

        result = self.manserv.GetPartnerUrl(partnerId = partnerId, urlType = {'value': 'Undefined',})
        self.assertEqual(result, '')

        resultLogo = self.manserv.GetPartnerUrl(partnerId = partnerId, urlType = {'value': 'Logo',})
        self.assertEqual(resultLogo, 'http://www.iaso.com/ipad/logo.png')

        resultPresentation = self.manserv.GetPartnerUrl(partnerId = partnerId,
                                                        urlType = {'value': 'PresentationDownload',})
        self.assertEqual(resultPresentation, 'http://www.iasobackup.com/ipad/presentation.zip')

        resultDedicate = self.manserv.GetPartnerUrl(partnerId = partnerId,
                                                        urlType = {'value': 'DedicatedQuoteModel',})
        self.assertEqual(resultDedicate, 'http://www.iasobackup.com/ipad/dsquote.xml')

        resultShared = self.manserv.GetPartnerUrl(partnerId = partnerId,
                                                        urlType = {'value': 'SharedQuoteModel',})
        self.assertEqual(resultShared, 'http://www.iasobackup.com/ipad/ssquote.xml')

        self._deletePartner()

    def test_GetRootPartnerName(self):
        self._createPartner()
        result = self.manserv.GetRootPartnerName()
        self.assertEqual(result, 'IASO')
        self._deletePartner()

    def test_ModifyPartner(self):
        newName = str(uuid.uuid4())
        partnerId = self._createPartner()
        newPartner = self._basePartnerInfo.copy()
        newPartner['id'] = partnerId
        newPartner['name'] = newName
        newPartner['serviceType'] = 'AllInclusive'
        newPartner['childServiceTypes']['string'] = ['AllInclusive', 'SoftwareOnly']
        newPartner['mailingOption'] = 'IncludeAll'

        result = self.manserv.ModifyPartner(**newPartner)
        self.assertIsNone(result)
        partnerInfo = self.manserv.GetPartnerInfoById(id = partnerId)
        self.assertEqual(partnerInfo.id, partnerId)
        self.assertEqual(partnerInfo.name, newName)
        self.assertEqual(partnerInfo.serviceType, newPartner['serviceType'])
        self.assertEqual(partnerInfo.childServiceTypes.string, newPartner['childServiceTypes']['string'])
        self.assertEqual(partnerInfo.mailingOption, newPartner['mailingOption'])

        self.executor.removePartner(newName, True)

    def test_RemovePartner(self):
        partnerId = self._createPartner()
        count = self._getPartnerCount()
        with self.assertRaises(Exception) as exc:
            self.manserv.RemovePartner(partnerId = partnerId)
        result = self._deletePartner()
        self.assertIsNone(result)
        countAfter = self._getPartnerCount()
        self.assertEqual(count - 1, countAfter)

    def test_SetAdvancedPartnerProperties(self):
        partnerId = self._createPartner()
        self.manserv.EnumerateRegions()
        regionId = self.manserv.EnumerateRegions().regionInfo[0].id
        respUser = self.manserv.EnumerateUsers(partnerId = [partnerId,]).userInfo[0].id
        result = self.manserv.SetAdvancedPartnerProperties(partnerId = int(partnerId),
                                                           regionId = int(regionId),
                                                           responsibleUserId = int(respUser))
        self.assertIsNone(result)
        advProperties = self.manserv.GetAdvancedPartnerProperties(partnerId = partnerId)
        self.assertEqual(advProperties.regionId, int(regionId))
        self.assertEqual(advProperties.responsibleUserId, int(respUser))

        self._deletePartner()

    def test_SetExternalPartnerProperties(self):
        partnerId = self._createPartner()
        properties = {
            'advCode': 'advCode',
            'channelPartnerId': 1,
            'greatPlainsId': 1,
            'locCode': 'locCode',
            'partnerId': int(partnerId),
            'searchTerm': 'searchTerm',
        }
        result = self.manserv.SetExternalPartnerProperties(**properties)
        self.assertIsNone(result)
        extProperties = self.manserv.EnumerateExternalPartnerProperties(partnerId = [partnerId, ])
        self.assertTrue(self._compareBaseDictionaryAndResultObject(properties,
                                                                   extProperties.externalPartnerProperties[0]))
        self._deletePartner()

    @unittest.skip('Fix rights for skinning folder')
    def test_SetPartnerBranding(self):
        #TODO: rights for skinning folder?
        archiveInfo = {
            'type': {'value': 'Zip',},
            'content': 'Test Content',
        }
        partnerId = self._createPartner()

        result = self.manserv.SetPartnerBranding(partnerId = partnerId, brandingArchive = archiveInfo)

        self._deletePartner()

    def test_SetPartnerPriceCurrency(self):
        partnerId = self._createPartner()
        result = self.manserv.SetPartnerPriceCurrency(partnerId = partnerId, currency = 'testCurrency')
        self.assertIsNone(result)
        currency = self.manserv.GetPartnerPriceCurrency(partnerId = partnerId)
        #self.assertEqual(currency, 'testCurrency')
        self.assertEqual(currency, 'EUR')

        self._deletePartner()

    def test_SetPartnerUrl(self):
        partnerId = self._createPartner()

        result = self.manserv.SetPartnerUrl(partnerId = partnerId,
                                            urlType = {'value': 'Logo',},
                                            url = 'http://www.iaso.com')
        self.assertIsNone(result)
        url = self.manserv.GetPartnerUrl(partnerId = partnerId, urlType = {'value': 'Logo',})
        #self.assertEqual(url, 'http://www.iaso.com')
        self.assertEqual(url, 'http://www.iaso.com/ipad/logo.png')

        self._deletePartner()

    def test_AddRegion(self):
        name = str(uuid.uuid4())
        result = self.manserv.AddRegion(name = name)
        self.assertTrue(result.isnumeric())

    def test_EnumerateRegions(self):
        result = self.manserv.EnumerateRegions()
        self.assertGreater(len(result.regionInfo), 7)
#---
    def _createPartner(self):
        self._partnerName = str(uuid.uuid4())
        self._basePartnerInfo['name'] = self._partnerName
        return self.manserv.AddPartner(partnerInfo = self._basePartnerInfo)

    def _deletePartner(self):
        return self.executor.removePartner(self._partnerName, True)

    def _compareBaseDictionaryAndResultObject(self, basedict, resultobj):
        resultdict = asdict(resultobj)
        for key, value in basedict.iteritems():
            if not isinstance(value, dict):
                if resultdict.has_key(key):
                    if value != resultdict[key]:
                        print('basedict[%s]=%s; resultdict[%s]=%s' %(key, value, key, resultdict[key]))
                        return False
                else:
                    print('Key %s not found in result dictionary' %key)
        return True

    def _getPartnerCount(self):
        return self.sudsSequenceLen(self.manserv.EnumeratePartners(fetchRecursively=False,
                                                                   parentPartnerId=int(self._parentId)),
                                    'partnerInfo')


if __name__ == "__main__":
    unittest.main()

